package com.zpark.transaction.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.shanjupay.paymentagent.api.conf.AliConfigParam;
import com.shanjupay.paymentagent.api.dto.AlipayBean;
import com.shanjupay.paymentagent.api.dto.PaymentResponseDTO;
import com.zpark.jushanpay.common.domain.BusinessException;
import com.zpark.jushanpay.common.domain.CommonErrorCode;
import com.zpark.jushanpay.common.util.AmountUtil;
import com.zpark.jushanpay.common.util.EncryptUtil;
import com.zpark.jushanpay.common.util.PaymentUtil;
import com.zpark.transaction.api.dto.PayChannelParamDTO;
import com.zpark.transaction.api.dto.PayOrderDTO;
import com.zpark.transaction.api.dto.QRCodeDTO;
import com.zpark.transaction.api.service.IPayChannelService;
import com.zpark.transaction.api.service.ITransactionService;
import com.zpark.transaction.service.convert.IPayOrderConvert;
import com.zpark.transaction.service.entity.PayOrder;
import com.zpark.transaction.service.mapper.IPayOrderMapper;
import com.zpark.transaction.service.vo.OrderConfirmVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

/**
 * 订单交易业务层实现类
 */
@Service
@Slf4j
public class TransactionServiceImpl implements ITransactionService {

    @Value("${shanjupay.payurl}")
    private String payurl;
    @Autowired
    private IPayOrderMapper payOrderMapper;
    @Autowired
    private IPayChannelService payChannelService;

    // 定义支付宝H5支付订单号
    private String alipayH5PayOrderNo;


    /**
     * 生成门店二维码
     * @param dto 门店+商户+应用信息
     * @return
     * @throws BusinessException
     */
    @Override
    public String createStoreQRCode(QRCodeDTO dto) throws BusinessException {
        // 1、校验商户id与应用id+门店id是否合法，定义私有方法实现checkMerchantIdAndAppIdAndStoreId
        // 2、组装url所需要的数据  payOrder
        PayOrder payOrder = new PayOrder();
        // 设置商户id
        payOrder.setMerchantId(dto.getMerchantId());
        // 设置门店id
        payOrder.setStoreId(dto.getStoreId());
        // 设置应用id
        payOrder.setAppId(dto.getAppId());
        // 设置订单标题
        payOrder.setSubject(dto.getSubject());
        // 交易渠道 服务类型，要写为c扫b的服务类型
        payOrder.setChannel("shanju_c2b");
        // 订单附加信息body
        payOrder.setBody(dto.getBody());

        // 3、将payOrder对象转为json字符串
        String payOrderJson = JSON.toJSONString(payOrder);

        // 4、base64编码
        String result = EncryptUtil.encodeUTF8StringBase64(payOrderJson);
        // 5、目标是生成一个支付入口 的url，需要携带参数将传入的参数转成json，用base64编码
        // 返回url
        return payurl + result;
    }

    /**
     * 提交订单
     * 支付宝订单保存
     * @param dto 订单对象
     * @return
     * @throws BusinessException
     */
    @Override
    public String submitOrderByAli(PayOrderDTO dto) throws BusinessException {
        //调用支付代理服务请求第三方支付系统
        // 根据应用、服务类型、支付渠道查询支付渠道参数
        // 根据应用的appId和平台服务类型编码以及原始支付渠道编码查询原始支付渠道参数配置数据
        PayChannelParamDTO payChannelParamDTO =
                payChannelService.queryPayChannelParamByAppAndPlatform(
                        dto.getAppId(),
                        dto.getChannel(),
                        "ALIPAY_WAP");

        if(payChannelParamDTO==null){
            throw new BusinessException(CommonErrorCode.E_300007);
        }

        // 设置商户id
        dto.setMerchantId(payChannelParamDTO.getMerchantId());
        // 设置支付渠道
        dto.setPayChannel("ALIPAY_WAP");
        // 保存订单数据
        PayOrderDTO payOrderDTO = save(dto);

        // 给支付宝h5支付方式的订单号赋值
        alipayH5PayOrderNo = payOrderDTO.getOutTradeNo();

        //支付宝渠道参数
//        AliConfigParam aliConfigParam = JSON.parseObject(payChannelParamDTO.getParam(),
//                AliConfigParam.class);
//        //字符编码
//        aliConfigParam.setCharset("utf‐8");

        return payChannelParamDTO.getParam();
    }

    /**
     * 根据订单号（交易号）查询订单信息
     * @param tradeNo 订单号
     * @return
     */
    @Override
    public PayOrderDTO queryPayOrder(String tradeNo) {
        // 根据订单号查询数据
        PayOrder payOrder = payOrderMapper.selectOne(
                new LambdaQueryWrapper<PayOrder>()
                        .eq(PayOrder::getOutTradeNo, tradeNo)
        );
        // 判断订单是否存在
        if (payOrder == null) {
            // 订单号不存在
            throw new BusinessException(CommonErrorCode.E_300011);
        }

        return IPayOrderConvert.INSTANCE.entityToDto(payOrder);
    }

    /**
     * 创建支付实体
     * @return
     */
    @Override
    public AlipayBean createAlipayBean() {
        // 创建支付实体
        //构建支付实体
        AlipayBean alipayBean = new AlipayBean();

        //根据订单号查询订单详情
        PayOrderDTO payOrderDTO = queryPayOrder(alipayH5PayOrderNo);

        // 设置订单号
        alipayBean.setOutTradeNo(alipayH5PayOrderNo);
        // 设置订单标题
        alipayBean.setSubject(payOrderDTO.getSubject());

        String totalAmount = null;//支付宝那边入参是元
        try{
            //将分转成元
            totalAmount = AmountUtil.changeF2Y(payOrderDTO.getTotalAmount().toString());
        }catch(Exception e){
            e.printStackTrace();
            throw new BusinessException(CommonErrorCode.E_300006);
        }
        // 设置订单金额
        alipayBean.setTotalAmount(totalAmount);
        // 设置订单的附加信息
        alipayBean.setBody(payOrderDTO.getBody());
        // 设置门店id
        alipayBean.setStoreId(payOrderDTO.getStoreId());
        // 设置订单超时时间
        alipayBean.setExpireTime("30m");

        return alipayBean;
    }


    /**
     * 创建支付宝订单
     * @param vo 订单实体
     * @param request 请求对象
     * @param response 响应对象
     */
    public void createAliPayOrder(@RequestBody OrderConfirmVO vo,
                                  HttpServletRequest request,
                                  HttpServletResponse response){

        // 调用支付渠道代理服务工程的接口实现支付宝支付
        // 响应支付宝支付页面
    }

    /**
     * 保存订单到自己的项目当中
     * @param dto
     */
    private PayOrderDTO save(PayOrderDTO dto){
        // 将dto转为entity
        PayOrder payOrder = IPayOrderConvert.INSTANCE.dtoToEntity(dto);

        // 创建订单号
        payOrder.setOutTradeNo(PaymentUtil.genUniquePayOrderNo());
        // 创建平台唯一订单号
        payOrder.setTradeNo(PaymentUtil.genUniquePayOrderNo());
        // 设置订单的创建时间
        payOrder.setCreateTime(LocalDateTime.now());
        // 设置订单的过期时间，为当前时间后30分钟
        payOrder.setExpireTime(LocalDateTime.now().plus(30, ChronoUnit.MINUTES));
        // 设置支付的货币类型为人民币
        payOrder.setCurrency("CNY");//设置支付币种
        // 设置订单的初始状态为未支付
        payOrder.setTradeState("0");//订单状态
        // 将元转为分存储到数据库
        payOrder.setTotalAmount(
                Integer.parseInt(
                        AmountUtil.changeY2F(dto.getTotalAmount().toString())
                )
        );

        // 将订单信息插入数据库
        int insert = payOrderMapper.insert(payOrder);

        // 将entity转为dto返回
        return IPayOrderConvert.INSTANCE.entityToDto(payOrder);
    }

}
